#coding=utf-8
'''
Created on 2011-8-8

@author: dokieyang
'''
import os
import time
import csv
import getopt,sys
import threading
import signal


class Log(object):
    '''
         日志工具类
    '''
    @staticmethod
    def getCureTime():
        return time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(time.time()))

    @staticmethod
    def getLogCurrTime():
        return "[" + time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(time.time())) +"]"
    @staticmethod
    def debug(msg):
        sys.stdout.write(Log.getLogCurrTime() + msg + "\n")
    
    @staticmethod
    def debugWithoutTime(msg):
        sys.stdout.write( msg + "\n")

class ATool(object):
    '''
    classdocs
    '''


    def __init__(self, csvFileName):
        '''
        Constructor
        '''
        self.cvsFileName = csvFileName
        self.csvFile = file(csvFileName,"wb")
        self.csvWriter = csv.writer(self.csvFile)
        signal.signal(signal.SIGINT, self.handler)
    
    @staticmethod
    def usage():
        """帮助信息 """
        print u"""
使用方法：ATool.py -o data.csv -n com.tencent.qqpim or AToll.py -o data.csv -p 174
-d device  use USB connected device
-p process id   the application process id
-h help
-o outputFile csv file to store the result
-n appName your application package name
        """
        
               
    def getPIDByAppName(self, appName):
        """取得appName对应的PID"""
        
        onceAdbShellCmd ="adb -d shell top -n 1"
        adbShellResult = os.popen(onceAdbShellCmd,"r")
        for eachLine in adbShellResult:
            if eachLine != "\r\n" and eachLine != "":
                detaiList = eachLine.split()
                if len(detaiList) !=  0 and len(detaiList) == 9 and detaiList[0] != "User" and  detaiList[0] != "PID":
                    if cmp(appName, detaiList[8]) == 0:
                        return detaiList[0]
        return None
    
    
    def getAppNameByPID(self, pid):
        """通过PID取得appName"""
        
        onceAdbShellCmd ="adb -d shell top -n 1"
        adbShellResult = os.popen(onceAdbShellCmd,"r")
        for eachLine in adbShellResult:
            if eachLine != "\r\n" and eachLine != "":
                detaiList = eachLine.split()
                if len(detaiList) !=  0 and len(detaiList) == 9 and detaiList[0] != "User" and  detaiList[0] != "PID":
                    if cmp(pid, detaiList[0]) == 0:
                        return detaiList[8]
        return None
    
    
    def initCsvFile(self):
        colName = ["Time","CPU","Memory(KB)","threadNumber"]
        self.csvWriter.writerow(colName)
        
        
    def writeToVCsvFile(self,dataCol):
        """ 把数据写到csv文件中"""
        try:
            fp = open(self.csvFileName,"a")
            fp.writelines(dataCol)
            fp.writelines("\n")
        except IOError,e:
            raise e
        finally:
            fp.close()
        
            
        
    
    
    def getResult(self):
        """返回一个包含结果的list"""
        onceAdbShellCmd ="adb -d shell top -n 1"
        adbContent = os.popen(onceAdbShellCmd,"r")
        currTime = Log.getCureTime()
       
        for eachLine in adbContent:
            #print eachLine
            if eachLine != "\r\n" and eachLine != "":
                detaiList = eachLine.split()
                if len(detaiList) !=  0 and len(detaiList) ==  9  and detaiList[0] != "User" and  detaiList[0] != "PID":
                    if cmp(self.pid, detaiList[0]) == 0:
                        #print eachLine
                        CPUInfo = detaiList[1]
                        CPUInfoDigit = CPUInfo[:-1]
                        threadNumber = detaiList[3]
                        #VSS = detaiList[4][:-1]
                        RSS = detaiList[5][:-1]
                        result = [currTime, str(CPUInfoDigit) ,RSS,threadNumber ]
                        Log.debugWithoutTime(str(result))
                        return result
                
            
            
    def onStart(self,interval,appName, pid=0):    
        """启动数据收集"""
        if pid == 0:
            self.pid = self.getPIDByAppName(appName)
            self.appName = appName;
        else:
            self.pid = pid
            self.appName = self.getAppNameByPID(pid)
        
        if not self.pid or not self.appName:
            Log.debug(u"没有找到应用程序")
            return 
        
        
        Log.debug(u"找到应用程序,appName=" + self.appName + ", PID=" + self.pid)
        self.initCsvFile()
        
        self.monitorThread = threading.Thread(target=self.getResultByInterval,args=(interval,))
        self.monitorThread.start()
        
        
        while self.monitorThread.isAlive():
            try:
                pass
            except KeyboardInterrupt:
                self.onStop()
        
        return
    
    
    
    def getResultByInterval(self, interval):
        """取得数据结果，并写到csv文件"""
        Log.debug(u"开始收集结果")
        colName = ["Time","CPU%","Memory(KB)","threadNumber"]
        Log.debugWithoutTime(str(colName))
        while True:
            time.sleep(interval)
            result = self.getResult()
            
            if not result:
                continue
            try:
                self.csvWriter.writerow(result)
            except IOError,e:
                Log.debug(u"写入数据异常")
                raise e
            finally:
                pass
            
            
    
    def onStop(self):
        self.monitorThread.join(10)
        Log.debug(u"正在结束程序")
        try:
            while True:
                alive = False
                if self.monitorThread.isAlive():
                    alive = True
                    self.monitorThread._Thread__stop()
                if not alive:
                    break
        except:
            Log.debug(u"尝试结束线程失败")
                
        self.csvFile.flush()
        self.csvFile.close()
        Log.debug(u"关闭文件，结果保存在:" + os.path.dirname(__file__) + "\\" + self.cvsFileName)
      
      
        
    def handler(self,signum, frame):
        Log.debug(u"收到终止信号")
        self.onStop()
        sys.exit()
        
    
    @staticmethod
    def cmd():
        """处理输入"""
        interval = 1
        csvFileName = ""
        appName = ""
        PID = ""
        
        try:
            opts,args = getopt.getopt(sys.argv[1:],"ho:n:d:p:")
        except getopt.GetoptError:
            ATool.usage()
            sys.exit(2)
        for o, a in opts:
            if o in("-h", "--help"):
                ATool.usage()
                sys.exit()
            if o in ("-o"):
                csvFileName = a
            if o in ("-n"):
                appName = a
            if o in ("-d"):
                interval = a
            if o in ("-p"):
                PID = a
         
        if PID:
            if not csvFileName or appName:
                ATool.usage()
                sys.exit()
        if appName:
            if not csvFileName or PID:
                ATool.usage()
                sys.exit()
                
        #print appName, " ", csvFileName, PID
        
        if not interval:
            interval = 1
        return (csvFileName, appName, PID, interval)
        
        
if __name__ == '__main__':
    
    csvFileName, appName, PID, interval = ATool.cmd()
    
    if PID:
        atool = ATool(csvFileName)
        atool.onStart(interval, None, PID)
    if appName:
        atool = ATool(csvFileName)
        atool.onStart(interval, appName)



